import {
	Tile3d
} from '../Thing/Tile3d.js';
import {
	Model
} from '../Thing/Model.js';

class ModelLayer {
	
	constructor(viewer) {
		this._viewer = viewer;
		this._scene = viewer.scene;
		this.map = new Map();
	}
	
	/**
	 * @description 添加模型
	 * @param {Object} option {
		 type:0-普通模型 1-Cesium3DTileset
		 model:{
		 },
		 attributes:{
		 }
	 }
	 */
	add(options) {
		let thing = null;
		if (options instanceof Array) {
			for (var option of options) {
				if (0 == option.type) {
					thing=this.convertModel(option.model, option.attributes)
					this._scene.primitives.add(thing.obj);
				} else if (1 == option.type) {
					thing = this._scene.primitives.add(this.convertTile3d(option.model, option.attributes));
				}
				if (thing != null && !this.map.has(thing.id)) {
					this.map.set(thing.id, thing);
				}
			}
		} else {
			if (0 == options.type) {
				thing = this.convertModel(options.model, options.attributes);
				this._scene.primitives.add(thing.obj);
			} else if (1 == options.type) {
				thing = this._scene.primitives.add(this.convertTile3d(options.model, options.attributes));
			}
			if (thing != null && !this.map.has(thing.id)) {
				this.map.set(thing.id, thing);
			}
		}
		return thing;
	}
	/**
	 * @description 删除三维图层
	 * @param {Object} id
	 */
	delete(ids, fn) {
		if (ids instanceof Array) {
			for (var id of ids) {
				if (this.map.has(id)) {
					this._scene.primitives.remove(this.map.get(id));
					this.map.delete(id);
				}
			}
		} else {
			if (this.map.has(ids)) {
				this._scene.primitives.remove(this.map.get(ids));
				this.map.delete(ids);
			}
		}
	}
	
	/**
	 * @description 显示
	 * @param {Object} ids
	 * @param {Object} fn
	 */
	show(ids, fn) {
		if (ids instanceof Array) {
			for (var id of ids) {
				if (this.map.has(id)) {
					this.map.get(id).show = true;
				}
			}
		} else {
			if (this.map.has(ids)) {
				this.map.get(ids).show = true;
			}
		}
	}
	
	/**
	 * @description 隐藏
	 * @param {Object} ids
	 * @param {Object} fn
	 */
	hide(ids, fn) {
		if (ids instanceof Array) {
			for (var id of ids) {
				if (this.map.has(id)) {
					this.map.get(id).show = false;
				}
			}
		} else {
			if (this.map.has(ids)) {
				this.map.get(ids).show = false;
			}
		}
	}
	
	/**
	 * @description 获取
	 * @param {Object} ids
	 * @param {Object} fn
	 */
	get(ids, fn) {
		if (ids instanceof Array) {
			if (ids instanceof Array) {
				var modles = [];
				for (var id of ids) {
					if (this.map.has(id)) {
						modles.push(this.map.get(id));
					}
				}
				return modles;
			} else {
				if (this.map.has(ids)) {
					return this.map.get(ids);
				}
			}
		}
	}
	/**
	 * @description 定位
	 * @param {Object} option
	 * @param {Object} fn
	 */
	focus(option,fn){
		if (this.map.has(option.id)) {
			let thing=this.map.get(option.id);
			if(thing.location){
				if(option.distance){
					thing.location.z+=option.distance
				}
				let rotation;
				if(option.rotation){
					rotation=option.rotation;
				}else{
					rotation=thing.rotation;
				}
				this._viewer.cam.fly({
					location:thing.location,
					rotation:rotation,
				})
			}
		}
	}
	/**
	 * @description 设置高亮
	 * @param {Object} options{
		 ids:模型ids(数组或字符串)
	 }
	 * @param {Object} fn
	 */
	setHighlight(options,fn){
		
		let thing=this.map.get(option.id)
		if(thing){
			console.log(thing,thing.properties);
		}
		
	}
	/**
	 * @description 取消高亮
	 * @param {Object} options{
		  ids:模型ids(数组或字符串)
	 }
	 * @param {Object} fn
	 */
	cancelHighlight(options,fn){
		
	}
	showActor(){
		
	}
	hideActor(){
		
	}
	focusActor(){
		
	}
	highlightActor(){
		
	}
	stopHighlightActor(){
		
	}
	showAllActors(){
		
	}
	hideAllActors(){
		
	}
	
	/**
	 * @description 设置样式
	 * @param {Object} options{
		 ids:TileLayer的ID活ID集合
		 style:样式， 0：默认；1：X光；2：纯色；3：水晶体
		 color:颜色值
	 }
	 * @param {Object} fn
	 */
	setStyle(options,fn){
	}
	
	/**
	 * @description 转模型对象
	 * @param {Object} option
	 * @param {Object} properties
	 */
	convertModel(option, properties) {
		let model = {
			id: Cesium.defaultValue(option.id, Cesium.createGuid())
		};
		if (Cesium.defined(option.url)) {
			model.url = option.url;
		}
		if (Cesium.defined(option.basePath)) {
			model.basePath = option.basePath;
		}
		if (Cesium.defined(option.show)) {
			model.show = option.show;
		}
		if (Cesium.defined(option.scale)) {
			model.scale = option.scale;
		}
		if (Cesium.defined(option.minimumPixelSize)) {
			model.minimumPixelSize = option.minimumPixelSize;
		}
		if (Cesium.defined(option.maximumScale)) {
			model.maximumScale = option.maximumScale;
		}
		if (Cesium.defined(option.allowPicking)) {
			model.allowPicking = option.allowPicking;
		}
		if (Cesium.defined(option.incrementallyLoadTextures)) {
			model.incrementallyLoadTextures = option.incrementallyLoadTextures;
		}
		if (Cesium.defined(option.asynchronous)) {
			model.asynchronous = option.asynchronous;
		}
		if (Cesium.defined(option.clampAnimations)) {
			model.clampAnimations = option.clampAnimations;
		}
		if (Cesium.defined(option.shadows)) {
			model.shadows = option.shadows;
		}
		if (Cesium.defined(option.debugShowBoundingVolum)) {
			model.debugShowBoundingVolum = option.debugShowBoundingVolum;
		}
		if (Cesium.defined(option.debugWireframe)) {
			model.debugWireframe = option.debugWireframe;
		}
		if (Cesium.defined(option.heightReference)) {
			model.heightReference = option.heightReference;
		}
		if (Cesium.defined(option.scene)) {
			model.scene = option.scene;
		}
		if (Cesium.defined(option.distanceDisplayCondition)) {
			model.distanceDisplayCondition = option.distanceDisplayCondition;
		}
		if (Cesium.defined(option.color)) {
			model.color = option.color;
		}
		if (Cesium.defined(option.colorBlendMode)) {
			model.colorBlendMode = option.colorBlendMode;
		}
		if (Cesium.defined(option.colorBlendAmount)) {
			model.colorBlendAmount = option.colorBlendAmount;
		}
		if (Cesium.defined(option.silhouetteColor)) {
			model.silhouetteColor = option.silhouetteColor;
		}
		if (Cesium.defined(option.silhouetteSize)) {
			model.silhouetteSize = option.silhouetteSize;
		}
		if (Cesium.defined(option.clippingPlanes)) {
			model.clippingPlanes = option.clippingPlanes;
		}
		if (Cesium.defined(option.dequantizeInShader)) {
			model.dequantizeInShader = option.dequantizeInShader;
		}
		if (Cesium.defined(option.credit)) {
			model.credit = option.credit;
		}
		if (Cesium.defined(option.backFaceCulling)) {
			model.backFaceCulling = option.backFaceCulling;
		}
		if (Cesium.defined(option.showOutline)) {
			model.showOutline = option.showOutline;
		}
		if (Cesium.defined(option.location)) {
			model.location = option.location;
		}
		if (Cesium.defined(option.rotation)) {
			model.rotation = option.rotation;
		}
		
		let hpRoll = new Cesium.HeadingPitchRoll(
			Cesium.Math.toRadians((model.rotation&&model.rotation.heading ?model.rotation.heading:0 )),
			Cesium.Math.toRadians((model.rotation&&model.rotation.pitch ?model.rotation.pitch:0 )),
			Cesium.Math.toRadians((model.rotation&&model.rotation.roll ?model.rotation.roll:0 ))
		);
		let fixedFrameTransform = Cesium.Transforms.eastNorthUpToFixedFrame;
		let cartesian3=Cesium.Cartesian3.fromDegrees(model.location.x*1, model.location.y*1,model.location.z*1);
		model.modelMatrix=Cesium.Transforms.headingPitchRollToFixedFrame(cartesian3, hpRoll, this._viewer.scene.globe.ellipsoid, fixedFrameTransform);
		return new Model({
			model: model,
			attributes: properties
		});
	}
	/**
	 * @description 转Tile3d对象
	 * @param {Object} option
	 * @param {Object} properties
	 */
	convertTile3d(option, properties) {
		let model = {
			id: Cesium.defaultValue(option.id, Cesium.createGuid())
		};
		if (Cesium.defined(option.url)) {
			model.url = option.url;
		}
		if (Cesium.defined(option.show)) {
			model.show = option.show;
		}
		if (Cesium.defined(option.shadows)) {
			model.shadows = option.shadows;
		}
		if (Cesium.defined(option.maximumScreenSpaceError)) {
			model.maximumScreenSpaceError = option.maximumScreenSpaceError;
		}
		if (Cesium.defined(option.maximumMemoryUsage)) {
			model.maximumMemoryUsage = option.maximumMemoryUsage;
		}
		if (Cesium.defined(option.cullWithChildrenBounds)) {
			model.cullWithChildrenBounds = option.cullWithChildrenBounds;
		}
		if (Cesium.defined(option.cullRequestsWhileMoving)) {
			model.cullRequestsWhileMoving = option.cullRequestsWhileMoving;
		}
		if (Cesium.defined(option.cullRequestsWhileMovingMultiplier)) {
			model.cullRequestsWhileMovingMultiplier = option.cullRequestsWhileMovingMultiplier;
		}
		if (Cesium.defined(option.preloadWhenHidden)) {
			model.preloadWhenHidden = option.preloadWhenHidden;
		}
		if (Cesium.defined(option.preloadFlightDestinations)) {
			model.preloadFlightDestinations = option.preloadFlightDestinations;
		}
		if (Cesium.defined(option.preferLeaves)) {
			model.preferLeaves = option.preferLeaves;
		}
		if (Cesium.defined(option.dynamicScreenSpaceError)) {
			model.dynamicScreenSpaceError = option.dynamicScreenSpaceError;
		}
		if (Cesium.defined(option.dynamicScreenSpaceErrorDensity)) {
			model.dynamicScreenSpaceErrorDensity = option.dynamicScreenSpaceErrorDensity;
		}
		if (Cesium.defined(option.dynamicScreenSpaceErrorFactor)) {
			model.dynamicScreenSpaceErrorFactor = option.dynamicScreenSpaceErrorFactor;
		}
		if (Cesium.defined(option.dynamicScreenSpaceErrorHeightFalloff)) {
			model.dynamicScreenSpaceErrorHeightFalloff = option.dynamicScreenSpaceErrorHeightFalloff;
		}
		if (Cesium.defined(option.progressiveResolutionHeightFraction)) {
			model.progressiveResolutionHeightFraction = option.progressiveResolutionHeightFraction;
		}
		if (Cesium.defined(option.foveatedScreenSpaceError)) {
			model.foveatedScreenSpaceError = option.foveatedScreenSpaceError;
		}
		if (Cesium.defined(option.foveatedConeSize)) {
			model.foveatedConeSize = option.foveatedConeSize;
		}
		if (Cesium.defined(option.foveatedMinimumScreenSpaceErrorRelaxation)) {
			model.foveatedMinimumScreenSpaceErrorRelaxation = option.foveatedMinimumScreenSpaceErrorRelaxation;
		}
		if (Cesium.defined(option.foveatedInterpolationCallback)) {
			model.foveatedInterpolationCallback = option.foveatedInterpolationCallback;
		}
		if (Cesium.defined(option.foveatedTimeDelay)) {
			model.foveatedTimeDelay = option.foveatedTimeDelay;
		}
		if (Cesium.defined(option.skipLevelOfDetail)) {
			model.skipLevelOfDetail = option.skipLevelOfDetail;
		}
		if (Cesium.defined(option.baseScreenSpaceError)) {
			model.baseScreenSpaceError = option.baseScreenSpaceError;
		}
		if (Cesium.defined(option.skipScreenSpaceErrorFactor)) {
			model.skipScreenSpaceErrorFactor = option.skipScreenSpaceErrorFactor;
		}
		if (Cesium.defined(option.skipLevels)) {
			model.skipLevels = option.skipLevels;
		}
		if (Cesium.defined(option.immediatelyLoadDesiredLevelOfDetail)) {
			model.immediatelyLoadDesiredLevelOfDetail = option.immediatelyLoadDesiredLevelOfDetail;
		}
		if (Cesium.defined(option.loadSiblings)) {
			model.loadSiblings = option.loadSiblings;
		}
		if (Cesium.defined(option.clippingPlanes)) {
			model.clippingPlanes = option.clippingPlanes;
		}
		if (Cesium.defined(option.classificationType)) {
			model.classificationType = option.classificationType;
		}
		if (Cesium.defined(option.ellipsoid)) {
			model.ellipsoid = option.ellipsoid;
		}
		if (Cesium.defined(option.pointCloudShading)) {
			model.pointCloudShading = option.pointCloudShading;
		}
		if (Cesium.defined(option.imageBasedLightingFactor)) {
			model.imageBasedLightingFactor = option.imageBasedLightingFactor;
		}
		if (Cesium.defined(option.lightColor)) {
			model.lightColor = option.lightColor;
		}
		if (Cesium.defined(option.luminanceAtZenith)) {
			model.luminanceAtZenith = option.luminanceAtZenith;
		}
		if (Cesium.defined(option.lightColor)) {
			model.lightColor = option.lightColor;
		}
		if (Cesium.defined(option.sphericalHarmonicCoefficients)) {
			model.sphericalHarmonicCoefficients = option.sphericalHarmonicCoefficients;
		}
		if (Cesium.defined(option.specularEnvironmentMaps)) {
			model.specularEnvironmentMaps = option.specularEnvironmentMaps;
		}
		if (Cesium.defined(option.debugHeatmapTilePropertyName)) {
			model.debugHeatmapTilePropertyName = option.debugHeatmapTilePropertyName;
		}
		if (Cesium.defined(option.debugFreezeFrame)) {
			model.debugFreezeFrame = option.debugFreezeFrame;
		}
		if (Cesium.defined(option.debugColorizeTiles)) {
			model.debugColorizeTiles = option.debugColorizeTiles;
		}
		if (Cesium.defined(option.debugWireframe)) {
			model.debugWireframe = option.debugWireframe;
		}
		if (Cesium.defined(option.debugShowBoundingVolume)) {
			model.debugShowBoundingVolume = option.debugShowBoundingVolume;
		}
		if (Cesium.defined(option.debugShowContentBoundingVolume)) {
			model.debugShowContentBoundingVolume = option.debugShowContentBoundingVolume;
		}
		if (Cesium.defined(option.debugShowViewerRequestVolume)) {
			model.debugShowViewerRequestVolume = option.debugShowViewerRequestVolume;
		}if (Cesium.defined(option.debugShowGeometricError)) {
			model.debugShowGeometricError = option.debugShowGeometricError;
		}
		if (Cesium.defined(option.debugShowRenderingStatistics)) {
			model.debugShowRenderingStatistics = option.debugShowRenderingStatistics;
		}
		if (Cesium.defined(option.debugShowMemoryUsage)) {
			model.debugShowMemoryUsage = option.debugShowMemoryUsage;
		}
		if (Cesium.defined(option.debugShowUrl)) {
			model.debugShowUrl = option.debugShowUrl;
		}
		if (Cesium.defined(option.heightOffset)) {
			model.heightOffset = option.heightOffset;
		}
		if (Cesium.defined(option.location)) {
			model.location = option.location;
		}
		if (Cesium.defined(option.rotation)) {
			model.rotation = option.rotation;
		}
		if (Cesium.defined(option.scale)) {
			model.scale = option.scale;
		}
		return new Tile3d({
			model: model,
			attributes: properties
		});
	}

	/**
	 * @description 销毁
	 */
	destroy() {
		delete this._scene
		delete this._viewer
		return Cesium.destroyObject(this);
	}
}
export {
	ModelLayer
}
